package com.pt.controller;

import com.pt.common.ApiResponse;
import com.pt.common.Result;
import com.pt.common.constant.EmailVerificationType;
import com.pt.dto.request.LoginRequest;
import com.pt.dto.request.PasswordResetRequest;
import com.pt.dto.request.RegisterRequest;
import com.pt.dto.response.AuthResponse;
import com.pt.entity.User;
import com.pt.service.EmailService;
import com.pt.service.UserService;
import com.pt.security.JwtTokenProvider;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

@RestController
@RequestMapping("/api/auth")
@Api(value = "认证接口", tags = "认证接口", description = "用户注册、登录、邮箱验证等认证相关的API接口")
public class AuthController {
    
    private final UserService userService;
    private final EmailService emailService;
    private final JwtTokenProvider tokenProvider;
    
    @Autowired
    public AuthController(UserService userService, EmailService emailService, JwtTokenProvider tokenProvider) {
        this.userService = userService;
        this.emailService = emailService;
        this.tokenProvider = tokenProvider;
    }
    
    @PostMapping("/register")
    @ApiOperation(value = "用户注册", notes = "通过邀请码注册新用户账号")
    public ApiResponse<?> register(@Valid @RequestBody @ApiParam(value = "注册请求参数", required = true) RegisterRequest request) {
        try {
            // 注册用户（不返回token，用户状态为待验证）
            userService.registerUser(request);
            
            // 发送邮箱验证码
            User user = userService.getUserByUsername(request.getUsername());
            if (user != null) {
                emailService.sendRegistrationVerificationEmail(user.getId(), user.getEmail(), user.getUsername());
            }
            
            // 返回成功消息，提示用户验证邮箱
            java.util.Map<String, Object> result = new java.util.HashMap<>();
            result.put("message", "注册成功，请查收邮箱验证码并完成验证");
            result.put("email", request.getEmail());
            result.put("needVerification", true);
            
            return ApiResponse.success(result);
        } catch (RuntimeException e) {
            // 捕获业务异常（如邀请码无效、用户名已存在等）
            return ApiResponse.error(e.getMessage());
        } catch (Exception e) {
            // 捕获其他异常
            return ApiResponse.error("注册失败：" + e.getMessage());
        }
    }
    
    @PostMapping("/login")
    @ApiOperation(value = "用户登录", notes = "用户名密码登录，返回JWT令牌")
    public Result<User> login(@RequestBody LoginRequest request) {
        User user = userService.login(request.getUsername(), request.getPassword());
        if (user != null) {
            // 更新最后登录时间
            userService.updateLastLogin(user.getId());
            // 生成token
            String token = tokenProvider.generateToken(user.getId());
            user.setToken(token);
            return Result.success(user);
        }
        return Result.error("用户名或密码错误");
    }
    
    @GetMapping("/verify-email")
    @ApiOperation(value = "验证邮箱", notes = "通过验证码验证用户邮箱并完成注册")
    public ApiResponse<?> verifyEmail(@RequestParam @ApiParam(value = "邮箱验证码", required = true) String code) {
        try {
            AuthResponse authResponse = emailService.verifyEmailAndCompleteRegistration(code);
            if (authResponse != null) {
                return ApiResponse.success(authResponse);
            } else {
                return ApiResponse.error("验证失败，验证码可能已过期或不存在");
            }
        } catch (RuntimeException e) {
            return ApiResponse.error(e.getMessage());
        } catch (Exception e) {
            return ApiResponse.error("验证失败：" + e.getMessage());
        }
    }
    
    @PostMapping("/forgot-password")
    @ApiOperation(value = "忘记密码", notes = "发送密码重置邮件到指定邮箱")
    public ApiResponse<?> forgotPassword(@RequestParam @ApiParam(value = "用户邮箱地址", required = true) String email) {
        User user = userService.lambdaQuery().eq(User::getEmail, email).one();
        if (user == null) {
            return ApiResponse.error("该邮箱未注册");
        }
        
        emailService.sendPasswordResetEmail(user.getId(), user.getEmail(), user.getUsername());
        return ApiResponse.success("密码重置邮件已发送，请查收");
    }
    
    @PostMapping("/reset-password")
    @ApiOperation(value = "重置密码", notes = "通过邮箱验证码重置用户密码")
    public ApiResponse<?> resetPassword(@Valid @RequestBody @ApiParam(value = "密码重置请求参数", required = true) PasswordResetRequest request) {
        boolean success = emailService.resetPassword(request.getCode(), request.getNewPassword());
        if (success) {
            return ApiResponse.success("密码重置成功");
        } else {
            return ApiResponse.error("密码重置失败，验证码可能已过期或不存在");
        }
    }
    
    @GetMapping("/test-password")
    @ApiOperation(value = "测试密码匹配", notes = "临时接口，用于调试密码问题")
    public ApiResponse<?> testPassword(@RequestParam String username, @RequestParam String password) {
        try {
            // 获取用户
            User user = userService.getUserByUsername(username);
            if (user == null) {
                return ApiResponse.error("用户不存在");
            }
            
            // 获取PasswordEncoder
            org.springframework.security.crypto.password.PasswordEncoder encoder = 
                new org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder();
            
            // 测试密码匹配
            boolean matches = encoder.matches(password, user.getPassword());
            
            java.util.Map<String, Object> result = new java.util.HashMap<>();
            result.put("username", user.getUsername());
            result.put("passwordHash", user.getPassword());
            result.put("inputPassword", password);
            result.put("matches", matches);
            
            return ApiResponse.success(result);
        } catch (Exception e) {
            return ApiResponse.error("测试失败：" + e.getMessage());
        }
    }
    
    /**
     * 获取客户端真实IP地址
     */
    private String getClientIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        
        // 如果是多级代理，取第一个IP
        if (ip != null && ip.contains(",")) {
            ip = ip.split(",")[0].trim();
        }
        
        return ip;
    }
} 